package com.moji.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.moji.common.entity.MyPage;
import com.moji.common.utils.PageUtil;
import com.moji.entity.*;
import com.moji.entity.dto.QueryFlowDto;
import com.moji.entity.vo.AuditFlowVo;
import com.moji.entity.vo.FlowVo;
import com.moji.entity.vo.MjFlowVo;
import com.moji.mapper.MjFlowMapper;
import com.moji.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moji.util.IdGenerator;
import com.moji.util.MoJiCommonUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 流程配置表 服务实现类
 * </p>
 *
 * @author ccl
 * @since 2024-07-27
 */
@Service
public class MjFlowServiceImpl extends ServiceImpl<MjFlowMapper, MjFlow> implements MjFlowService {

    @Resource
    private MjOrderService mjOrderService;

    @Resource
    private MjOrderDetailService mjOrderDetailService;

    @Resource
    private MjFlowConfigService mjFlowConfigService;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private MjUserService mjUserService;

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private MjProductDetailService productDetailService;

    @Resource
    private MjProductService productService;

    @Resource
    private IdGenerator idGenerator;
    @Resource
    private AlipayService alipayService;
    @Resource
    private WeChatService weChatService;



    @Override
    public MyPage<MjFlow> queryByPage(QueryFlowDto dto) {
        LambdaQueryWrapper<MjFlow> wrapper = new LambdaQueryWrapper<>();
        //状态
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getOrderCode()),MjFlow::getOrderCode
                ,dto.getOrderCode());
        wrapper.like(ObjectUtil.isNotEmpty(dto.getAuditStatus()),MjFlow::getAuditStatus
                ,dto.getAuditStatus());
        wrapper.eq(ObjectUtil.isNotEmpty(dto.getFlowType()),MjFlow::getFlowType
                ,dto.getFlowType());
        wrapper.like(ObjectUtil.isNotEmpty(dto.getSubmitName()),MjFlow::getSubmitName
                ,dto.getSubmitName());
        //创建时间倒叙
        wrapper.orderByDesc(MjFlow::getCreateTime);
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<MjFlow> mjFlows = list(wrapper);
        PageInfo<MjFlow> info = new PageInfo<>(mjFlows);
        return PageUtil.PageInfo2MyPage(info);
    }

    @Override
    public MjFlowVo detail(Long id) {
        MjFlowVo mjFlowVo=new MjFlowVo();
        MjFlow mjFlow=this.getById(id);
        if(mjFlow ==null){
            throw new RuntimeException("审批流程不存在,请核查!");
        }
        BeanUtils.copyProperties(mjFlow,mjFlowVo);

        //用户信息
        MjUser sysUser=mjUserService.getOne(new LambdaQueryWrapper<MjUser>()
        .eq(MjUser::getUserCode,mjFlow.getSubmitCode()));
        if(sysUser != null){
            BeanUtils.copyProperties(sysUser,mjFlowVo);
        }

        //产品信息
        MjProduct product=productService.getOne(new LambdaQueryWrapper<MjProduct>()
        .eq(MjProduct::getId,mjFlow.getProductCode()));
        LambdaQueryWrapper<MjProductDetail> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(MjProductDetail::getProductId,mjFlow.getProductCode());
        wrapper.eq(MjProductDetail::getProductType,mjFlow.getProductType());
        wrapper.last(" limit 1" );
        MjProductDetail productDetails=productDetailService.getOne(wrapper);
        if(product != null && productDetails != null){
            BeanUtils.copyProperties(productDetails,mjFlowVo);
            mjFlowVo.setProductName(product.getProductName());
        }
        //订单信息
        MjOrder mjOrder=mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>()
                .eq(MjOrder::getOrderCode,mjFlow.getOrderCode()));
        if(mjOrder != null){
            mjFlowVo.setOrderCode(mjOrder.getOrderCode());
            mjFlowVo.setOrderTime(mjOrder.getOrderTime());
            mjFlowVo.setOrderAmount(mjOrder.getOrderAmount());
            mjFlowVo.setApplicationReason(mjOrder.getApplicationReason());
            mjFlowVo.setApplicationReasonId(mjOrder.getApplicationReasonId());
            mjFlowVo.setApplicationRemark(mjOrder.getApplicationRemark());
            mjFlowVo.setPayTime(mjOrder.getPayTime());
            mjFlowVo.setPayType(mjOrder.getPayType());

        }

        LambdaQueryWrapper<MjOrderDetail> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(MjOrderDetail::getOrderCode, mjOrder.getOrderCode());
        List<MjOrderDetail> detailList = mjOrderDetailService.list(wrapper1);
        for (int i = 0; i < detailList.size(); i++) {
            if (detailList.get(i) != null) {
                if ("N1Y".equals(detailList.get(i).getServiceTimeCode())) {
                    if (detailList.get(i).getEffectTime() != null) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(detailList.get(i).getEffectTime());
                        calendar.add(Calendar.YEAR, 1);
                        detailList.get(i).setExpirationTime(calendar.getTime());
                    }

                } else if ("N2Y".equals(detailList.get(i).getServiceTimeCode())) {
                    {
                        if (detailList.get(i).getEffectTime() != null) {
                            Calendar calendar = Calendar.getInstance();
                            calendar.setTime(detailList.get(i).getEffectTime());
                            calendar.add(Calendar.YEAR, 2);
                            detailList.get(i).setExpirationTime(calendar.getTime());
                        }
                    }
                } else if ("T7D".equals(detailList.get(i).getServiceTimeCode())) {
                    if (detailList.get(i).getEffectTime() != null) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(detailList.get(i).getEffectTime());
                        calendar.add(Calendar.DAY_OF_MONTH, 7);
                        detailList.get(i).setExpirationTime(calendar.getTime());
                    }
                }

            }

        }
        mjFlowVo.setOrderDetailList(detailList);

        List<AuditFlowVo> auditFlowVos=new ArrayList<>();
        //流程类型：1-价格设置 2-价格调整
        MjFlowConfig mjFlowConfig=mjFlowConfigService.getOne(new LambdaQueryWrapper<MjFlowConfig>()
                .eq(MjFlowConfig::getFlowType,2));
        if(mjFlowConfig !=null){
            List<String> listCodes=Arrays.asList(mjFlowConfig.getRoleCode().split(","));
            List<String> listNames=new ArrayList<>();
            //角色信息
            List<SysRole> sysRoles=sysRoleService.list(new LambdaQueryWrapper<SysRole>()
                    .in(SysRole::getRoleCode,listCodes));
            sysRoles.forEach(sysRole -> {
                listNames.add(sysRole.getRoleName());
            });
            for(int i=0;i<listCodes.size();i++){
                AuditFlowVo flowVo2=new AuditFlowVo();
                //未审核
                if(mjFlowVo.getAuditStatus()==20){
                    flowVo2.setAuditCode(listCodes.get(i));
                    flowVo2.setAuditName(listNames.get(i));
                    flowVo2.setAuditStatus(mjFlowVo.getAuditStatus());
                }
                //审核完成
                if(mjFlowVo.getAuditStatus()==21){
                    List<String> userCodes=Arrays.asList(mjFlow.getAuditCode().split(","));
                    List<String> userNames=new ArrayList<>();
                    //用户信息
                    List<SysUser> sysUsers=sysUserService.list(new LambdaQueryWrapper<SysUser>()
                            .in(SysUser::getUserCode,userCodes));
                    sysUsers.forEach(user -> {
                        userNames.add(user.getUserName());
                    });
                    flowVo2.setAuditCode(userCodes.get(i));
                    flowVo2.setAuditName(userNames.get(i));
                    flowVo2.setAuditStatus(mjFlowVo.getAuditStatus());
                    if(i==0){//第一次审核
                        flowVo2.setAuditTime(mjFlow.getAuditTime1());
                    }
                    if(i==1){//第二次审核
                        flowVo2.setAuditTime(mjFlow.getAuditTime2());
                    }
                }
                auditFlowVos.add(flowVo2);
            }
        }
        if(mjFlowVo.getAuditStatus()==20){
            mjFlowVo.setAuditNodes(1+"");
        }else{
            mjFlowVo.setAuditNodes(2+"");
        }
        mjFlowVo.setAuditFlowVos(auditFlowVos);
        mjFlowVo.setId(mjFlow.getId());
        return mjFlowVo;
    }

    @Override
    public boolean add(MjFlow mjFlow) {
        String flowCode= idGenerator.idGenerator("SPLL");
        mjFlow.setFlowCode(flowCode);
        mjFlow.setCreateId(MoJiCommonUtils.getUserCode());
        mjFlow.setUpdateId(MoJiCommonUtils.getUserCode());
        mjFlow.setCreateTime(new Date());
        mjFlow.setUpdateTime(new Date());
        return this.save(mjFlow);
    }

    @Override
    public boolean audit(Long id) {
        MjFlow mjFlow=this.getById(id);
        if(mjFlow ==null){
            throw new RuntimeException("审批流程不存在,请核查!");
        }

        MjFlowConfig mjFlowConfig=mjFlowConfigService.getOne(new LambdaQueryWrapper<MjFlowConfig>()
                .eq(MjFlowConfig::getFlowType,mjFlow.getFlowType()));
        if(mjFlowConfig ==null){
            throw new RuntimeException("调价规则不存在无法审核,请核查!");
        }
        MjOrder mjOrder=mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>()
            .eq(MjOrder::getOrderCode,mjFlow.getOrderCode()));
        if(mjOrder==null){
            throw new RuntimeException("订单数据不存在,请核查!");
        }
        List<String> roles= Arrays.asList(mjFlowConfig.getRoleCode().split(","));
        //流程类型：1-价格设置 2-价格调整 3-申请退款
        if("1".equals(mjFlow.getFlowType())){

        }
        if("2".equals(mjFlow.getFlowType())){
            priceChangeAudit(mjFlow,mjFlowConfig,mjOrder,roles);
        }
        if("3".equals(mjFlow.getFlowType())){
            returnAmountAudit(mjFlow,mjFlowConfig,mjOrder,roles);
        }
        return true;
    }

    /**
     * 申请退款审核
     * @param mjFlow
     * @param mjFlowConfig
     * @param mjOrder
     * @param roles
     */
    private void returnAmountAudit(MjFlow mjFlow, MjFlowConfig mjFlowConfig, MjOrder mjOrder, List<String> roles) {
        //一级审批
        if(roles.size()==1){
            if(MoJiCommonUtils.getRoleCode().contains(mjFlowConfig.getRoleCode())){
                //审核状态20 - 待审核 21 - 已审核 22-已驳回
                mjOrder.setAuditStatus(21);
                //订单状态0 - 待支付 1 - 已完成 2-已取消 3-待退款 4—已退款 5—审核拒绝  6-订单超时失效 7-退款失败(拒绝)
                //判断订单是支付宝还是微信付款
                if("0".equals(mjOrder.getPayType()))
                {
                    //调用支付宝退款接口
                    try {
                        //暂时退款定为0.01
                        Boolean refund = alipayService.refund(mjOrder.getOrderCode(), "0.01");
                        if(refund)
                        {
                            mjOrder.setOrderStatus(4);
                            mjOrderService.updateById(mjOrder);

                            //更新流程审批节点
                            mjFlow.setAuditStatus(21);
                            mjFlow.setAuditTime1(new Date());
                            mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                            mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                            this.updateById(mjFlow);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else if("1".equals(mjOrder.getPayType()))
                {
                    try {
                        Boolean aBoolean = weChatService.refundOrder(mjOrder.getOrderCode(), mjOrder.getSpareString1());
                        if(aBoolean)
                        {
                            mjOrder.setOrderStatus(4);
                            mjOrderService.updateById(mjOrder);

                            //更新流程审批节点
                            mjFlow.setAuditStatus(21);
                            mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                            mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                            mjFlow.setAuditTime1(new Date());
                            this.updateById(mjFlow);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                else{
                    mjOrder.setOrderStatus(4);
                    mjOrderService.updateById(mjOrder);

                    //更新流程审批节点
                    mjFlow.setAuditStatus(21);
                    mjFlow.setAuditTime1(new Date());
                    mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                    mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                    this.updateById(mjFlow);
                }

            }else{
                throw new RuntimeException("该用户无权限审核,请核查!");
            }
        }
        //二级审批
        if(roles.size()==2){
            if(mjFlow.getSpareInt1()==1){//第一次审核
                if(MoJiCommonUtils.getRoleCode().contains(roles.get(0))){
                    mjOrder.setEditOrderAmount(mjFlow.getEditOrderAmount());
                    //审核状态20 - 待审核 21 - 已审核 22-已驳回
                    mjOrder.setAuditStatus(20);
                    //订单状态0 - 待支付 1 - 已完成 2-已取消 3-待退款 4—已退款 5—审核拒绝  6-订单超时失效
                    mjOrder.setOrderStatus(3);
                    mjOrderService.updateById(mjOrder);

                    //更新流程审批节点
                    mjFlow.setSpareInt1(2);
                    mjFlow.setAuditTime1(new Date());
                    mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                    mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                    this.updateById(mjFlow);
                }else{
                    throw new RuntimeException("该用户无权限审核,请核查!");
                }
            }
            if(mjFlow.getSpareInt1()==2){//第二次审核
                if(MoJiCommonUtils.getRoleCode().contains(roles.get(1))){
                    mjOrder.setSpareInt1(null);
                    //审核状态20 - 待审核 21 - 已审核 22-已驳回
                    mjOrder.setAuditStatus(21);
                    //订单状态0 - 待支付 1 - 已完成 2-已取消 3-待退款 4—已退款 5—审核拒绝  6-订单超时失效
                    //判断订单是支付宝还是微信付款
                    if("0".equals(mjOrder.getPayType()))
                    {
                        //调用支付宝退款接口
                        try {
                            //暂时退款定为0.01
                            Boolean refund = alipayService.refund(mjOrder.getOrderCode(), "0.01");
                            if(refund)
                            {
                                mjOrder.setOrderStatus(4);
                                mjOrderService.updateById(mjOrder);

                                //更新流程审批节点
                                mjFlow.setAuditStatus(21);
                                mjFlow.setAuditCode(mjFlow.getAuditCode()+","+MoJiCommonUtils.getUserCode());
                                mjFlow.setAuditName(mjFlow.getAuditName()+","+MoJiCommonUtils.getUserName());
                                mjFlow.setAuditTime2(new Date());
                                this.updateById(mjFlow);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }else if("1".equals(mjOrder.getPayType()))
                    {
                        try {
                            Boolean aBoolean = weChatService.refundOrder(mjOrder.getOrderCode(), mjOrder.getSpareString1());
                            if(aBoolean)
                            {
                                mjOrder.setOrderStatus(4);
                                mjOrderService.updateById(mjOrder);

                                //更新流程审批节点
                                mjFlow.setAuditStatus(21);
                                mjFlow.setAuditCode(mjFlow.getAuditCode()+","+MoJiCommonUtils.getUserCode());
                                mjFlow.setAuditName(mjFlow.getAuditName()+","+MoJiCommonUtils.getUserName());
                                mjFlow.setAuditTime2(new Date());
                                this.updateById(mjFlow);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    else{
                        mjOrder.setOrderStatus(4);
                        mjOrderService.updateById(mjOrder);

                        //更新流程审批节点
                        mjFlow.setAuditStatus(21);
                        mjFlow.setAuditCode(mjFlow.getAuditCode()+","+MoJiCommonUtils.getUserCode());
                        mjFlow.setAuditName(mjFlow.getAuditName()+","+MoJiCommonUtils.getUserName());
                        mjFlow.setAuditTime2(new Date());
                        this.updateById(mjFlow);
                    }
                }else{
                    throw new RuntimeException("该用户无权限审核,请核查!");
                }
            }
        }
    }

    /**
     * 价格调整审核
     * @param mjFlow
     * @param mjFlowConfig
     * @param mjOrder
     * @param roles
     */
    private void priceChangeAudit(MjFlow mjFlow, MjFlowConfig mjFlowConfig, MjOrder mjOrder,List<String> roles) {
        //一级审批
        if(roles.size()==1){
            if(MoJiCommonUtils.getRoleCode().contains(mjFlowConfig.getRoleCode())){
                mjOrder.setOrderAmount(mjFlow.getEditOrderAmount());
                mjOrder.setNewOrderAmount(mjFlow.getEditOrderAmount());
                mjOrder.setEditOrderAmount(null);
                //审核状态20 - 待审核 21 - 已审核 22-已驳回
                mjOrder.setAuditStatus(21);
                mjOrderService.updateById(mjOrder);

                //更新流程审批节点
                mjFlow.setAuditStatus(21);
                mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                mjFlow.setAuditTime1(new Date());
                this.updateById(mjFlow);
            }else{
                throw new RuntimeException("该用户无权限审核,请核查!");
            }
        }
        //二级审批
        if(roles.size()==2){
            if(mjFlow.getSpareInt1()==1){//第一次审核
                if(MoJiCommonUtils.getRoleCode().contains(roles.get(0))){
                    mjOrder.setEditOrderAmount(mjFlow.getEditOrderAmount());
                    //审核状态20 - 待审核 21 - 已审核 22-已驳回
                    mjOrder.setAuditStatus(20);
                    mjOrderService.updateById(mjOrder);

                    //更新流程审批节点
                    mjFlow.setSpareInt1(2);
                    mjFlow.setAuditTime1(new Date());
                    mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                    mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                    this.updateById(mjFlow);
                }else{
                    throw new RuntimeException("该用户无权限审核,请核查!");
                }
            }
            if(mjFlow.getSpareInt1()==2){//第二次审核
                if(MoJiCommonUtils.getRoleCode().contains(roles.get(1))){
                    mjOrder.setEditOrderAmount(null);
                    mjOrder.setNewOrderAmount(mjFlow.getEditOrderAmount());
                    mjOrder.setSpareInt1(null);
                    //审核状态20 - 待审核 21 - 已审核 22-已驳回
                    mjOrder.setAuditStatus(21);
                    mjOrderService.updateById(mjOrder);

                    //更新流程审批节点
                    mjFlow.setAuditStatus(21);
                    mjFlow.setAuditCode(mjFlow.getAuditCode()+","+MoJiCommonUtils.getUserCode());
                    mjFlow.setAuditName(mjFlow.getAuditName()+","+MoJiCommonUtils.getUserName());
                    mjFlow.setAuditTime2(new Date());
                    this.updateById(mjFlow);
                }else{
                    throw new RuntimeException("该用户无权限审核,请核查!");
                }
            }
        }
    }

    @Override
    public boolean refuse(Long id,String reason) {
        //流程类型：1-价格设置 2-价格调整
        MjFlow mjFlow=this.getById(id);
        if(mjFlow ==null){
            throw new RuntimeException("审批流程不存在,请核查!");
        }
        MjFlowConfig mjFlowConfig=mjFlowConfigService.getOne(new LambdaQueryWrapper<MjFlowConfig>()
                .eq(MjFlowConfig::getFlowType,mjFlow.getFlowType()));
        if(mjFlowConfig ==null){
            throw new RuntimeException("调价规则不存在无法审核,请核查!");
        }
        List<String> roles= Arrays.asList(mjFlowConfig.getRoleCode());
        for(String role:roles){
            if(MoJiCommonUtils.getRoleCode().contains(role)){
                //审核状态20 - 待审核 21 - 已审核 22-已驳回
                mjFlow.setAuditStatus(22);
                mjFlow.setUpdateTime(new Date());
                mjFlow.setAuditTime1(new Date());
                mjFlow.setAuditTime2(new Date());
                mjFlow.setAuditCode(MoJiCommonUtils.getUserCode());
                mjFlow.setAuditName(MoJiCommonUtils.getUserName());
                mjFlow.setReason(reason);
                break;
            }
        }
        //更新订单状态
        MjOrder mjOrder=mjOrderService.getOne(new LambdaQueryWrapper<MjOrder>()
            .eq(MjOrder::getOrderCode,mjFlow.getOrderCode()));
        if(mjOrder !=null){
            //订单状态0 - 待支付 1 - 已完成 2-已取消 3-待退款 4—已退款 5—审核拒绝  6-订单超时失效 7-退款失败
            /** 只有待支付状态可以申请改价，改价拒绝，原待支付状态不变 **/
//            if("2".equals(mjFlow.getFlowType())){
//                mjOrder.setOrderStatus(5);
//            }
            if("3".equals(mjFlow.getFlowType())){
                mjOrder.setOrderStatus(7);
            }
            mjOrder.setAuditStatus(22);
            mjOrderService.updateById(mjOrder);
        }
        return this.updateById(mjFlow);
    }

    @Override
    public boolean delete(Long id) {
        MjFlow mjFlow=this.getById(id);
        if(mjFlow ==null && mjFlow.getAuditStatus()==22){
            throw new RuntimeException("审批流程已审核通过不能删除,请核查!");
        }
        return this.removeById(id);
    }
}
